package com.ssy.lingxi.contract.job;


import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.contract.entity.SignatureLog;
import com.ssy.lingxi.contract.esign.api.SignApi;
import com.ssy.lingxi.contract.esign.constant.EsignConstants;
import com.ssy.lingxi.contract.esign.exception.EsignException;
import com.ssy.lingxi.contract.esign.response.SignFlowDetailResponse;
import com.ssy.lingxi.contract.model.bo.sign.SignFlowNotifyBO;
import com.ssy.lingxi.contract.model.constant.sign.SignatureLogStateEnum;
import com.ssy.lingxi.contract.repository.SignatureLogRepository;
import com.ssy.lingxi.contract.service.ISignatureService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 合同签署流程任务
 * @author yzc
 * @version 2.0.0
 * @date 2021/2/23
 */
@Slf4j
@Component
public class SignFlowCheckJobService {

    @Resource
    private SignatureLogRepository signatureLogRepository;
    @Resource
    private ISignatureService signatureService;
    @Resource
    private SignApi signApi;

    /**
     * 一周的时间(毫秒)
     */
    private static final long WEEK_TIME = 7 * Constants.DAY_TO_MILLISECONDS;

    public void checkSignFlow() {
        List<SignatureLog> signatureLogList = signatureLogRepository.findAll((Specification<SignatureLog>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList.add(cb.equal(root.get("state"), SignatureLogStateEnum.SIGNING.getCode()));
            predicateList.add(cb.greaterThan(root.get("createTime"), System.currentTimeMillis() - WEEK_TIME));

            return query.where(predicateList.toArray(new Predicate[predicateList.size()])).getRestriction();
        });
        log.info("签署流程查询: 当前有{}条数据在校验, ids:[{}]", signatureLogList.size(), signatureLogList.stream().map(e -> e.getId().toString()).collect(Collectors.joining(",")));
        for (SignatureLog signatureLog : signatureLogList) {
            String flowId = signatureLog.getFlowId();
            try {
                SignFlowDetailResponse response = signApi.signFlow().signFlowDetail(flowId);

                SignFlowNotifyBO signFlowNotifyBO = new SignFlowNotifyBO();
                signFlowNotifyBO.setFlowId(response.getFlowId());
                signFlowNotifyBO.setStatusDescription(response.getFlowDesc());

                if (Integer.valueOf(EsignConstants.SignFlowStatus.FINISH).equals(response.getFlowStatus())) {
                    // 流程状态为完成,即签署完成
                    signatureService.updateNotifySuccess(signFlowNotifyBO);
                } else if (
                        Integer.valueOf(EsignConstants.SignFlowStatus.CANCEL).equals(response.getFlowStatus())
                                || Integer.valueOf(EsignConstants.SignFlowStatus.PAST_DUE).equals(response.getFlowStatus())
                                || Integer.valueOf(EsignConstants.SignFlowStatus.REJECT).equals(response.getFlowStatus())
                ) {
                    // 流程状态为撤销,过期,拒签,即签署失败
                    signatureService.updateNotifyFail(signFlowNotifyBO);
                }
            } catch (EsignException e) {
                log.error("合同签署流程查询失败", e);
            }
        }
    }
}
